﻿using System.ComponentModel;
using System.Globalization;
using System.Xml.Serialization;
using sql_data_generator.FieldOptions;
using sql_data_generator.Randomizers;

namespace sql_data_generator.Entities
{
    public sealed class DataField : IDataField, IListItem, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private IRandomizer _randomizer;

        public DataField()
            : this(string.Empty, null, null, null)
        {
        }

        public DataField(string name, BaseFieldOptions fieldOptions, Field field, SubField subfield)
        {
            _name = name;
            _field = field;
            _subField = subfield;
            _fieldOptions = fieldOptions != null ? fieldOptions.Clone() : null;
            _id = GetHashCode().ToString(CultureInfo.InvariantCulture);
        }

        public object GetData()
        {
            return GetRandomizer().GetData();
        }

        private readonly string _id;
        [XmlIgnore]
        public string Id
        {
            get
            {
                return _id;
            }
        }

        private string _name;
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                if (value != _name)
                {
                    _name = value;
                    NotifyPropertyChanged("Name");
                }
            }
        }

        private BaseFieldOptions _fieldOptions;
        public BaseFieldOptions FieldOptions
        {
            get
            {
                return _fieldOptions;
            }
            set
            {
                if (value != _fieldOptions)
                {
                    _fieldOptions = value;
                    NotifyPropertyChanged("FieldOptions");
                }
            }
        }

        private Field _field;
        public Field Field
        {
            get
            {
                return _field;
            }
            set
            {
                if (value != _field)
                {
                    _field = value;
                    NotifyPropertyChanged("Field");
                }
            }
        }

        private SubField _subField;
        public SubField SubField
        {
            get
            {
                return _subField;
            }
            set
            {
                if (value != _subField)
                {
                    _subField = value;
                    NotifyPropertyChanged("SubField");
                }
            }
        }

        private IRandomizer GetRandomizer()
        {
            return _randomizer ?? (_randomizer = RandomizerFactory.GetRandomizer(FieldOptions));
        }

        // NotifyPropertyChanged will raise the PropertyChanged event passing the source property that is being updated.
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}